package com.xci.platform.auth.service;

import com.github.pagehelper.Page;
import com.xci.platform.annotation.OperateUser;
import com.xci.platform.annotation.QueryMap;
import com.xci.platform.auth.core.AuthConstant;
import com.xci.platform.auth.core.HistoryModel;
import com.xci.platform.auth.core.HistoryOperateType;
import com.xci.platform.auth.dao.ParamDao;
import com.xci.platform.auth.entity.ParamEntity;
import com.xci.platform.core.BoolMessage;
import com.xci.platform.helper.CoreHelper;
import com.xci.platform.helper.StringHelper;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 系统参数服务
 */
@Service
@CacheConfig(cacheNames = "paramCache")
public class ParamService extends AuthBaseService {

    /**
     * 参数数据访问对象
     */
    @Resource
    private ParamDao paramDao;

    /**
     * 缓存对象
     */
    @Resource(name = "paramCache")
    private Cache paramCache;

    /**
     * 保存参数
     *
     * @param entity   参数对象
     * @param isCreate 是否新建
     */
    @Validated
    @OperateUser
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(key = "'param:code:'+#entity.code")
    public BoolMessage save(ParamEntity entity, Boolean isCreate) {
        //添加名称简拼
        if (StringHelper.isBlank(entity.getSpell())) {
            entity.setSpell(StringHelper.getSpell(entity.getName()));
        }

        //参数名称验证
        if (paramDao.existByCode(entity.getCode(), entity.getId())) {
            String msg = StringHelper.format("参数编码 {} 已经存在", entity.getName());
            return new BoolMessage(false, msg);
        }

        String msg;
        long startTime = CoreHelper.startWatch();
        if (isCreate) {
            msg = StringHelper.format("新增参数 {}({})", entity.getCode(), entity.getName());
            paramDao.insert(entity);
            //region 历史记录
            operateHistory(buildHistory()
                    .operateType(HistoryOperateType.Insert)
                    .keyValue(entity.getId())
                    .message(msg)
                    .after(entity)
            );
            //endregion
        } else {
            msg = StringHelper.format("修改参数 {}({})", entity.getCode(), entity.getName());
            ParamEntity oldEntity = queryById(entity.getId());
            paramDao.update(entity);
            //region 历史记录
            operateHistory(buildHistory()
                    .operateType(HistoryOperateType.Update)
                    .keyValue(entity.getId())
                    .message(msg)
                    .before(oldEntity)
                    .after(entity)
            );
            //endregion
        }
        // 操作日志
        operateLog(AuthConstant.SystemModule.Param, msg, CoreHelper.stopWatch(startTime));
        return BoolMessage.True;
    }

    /**
     * 删除参数
     *
     * @param id 参数主键数组
     */
    @Validated
    @Transactional(rollbackFor = Exception.class)
    public BoolMessage delete(@NotEmpty(message = "请指定删除的参数主键") String id) {
        ParamEntity oldEntity = paramDao.queryById(id);
        if (oldEntity == null) return BoolMessage.True;

        long startTime = CoreHelper.startWatch();
        paramDao.delete(id);
        paramCache.evict(StringHelper.format("param:code:{}",oldEntity.getCode()));
        String msg = StringHelper.format("删除参数 {}({})", oldEntity.getCode(), oldEntity.getName());
        //region 历史记录
        operateHistory(buildHistory()
                .operateType(HistoryOperateType.Delete)
                .keyValue(id)
                .message(msg)
                .before(oldEntity)
        );
        //endregion
        // 操作日志
        operateLog(AuthConstant.SystemModule.Param, msg, CoreHelper.stopWatch(startTime));
        return BoolMessage.True;
    }

    /**
     * 根据参数主键获取参数对象
     *
     * @param id 参数主键
     * @return 返回指定参数主键的参数对象
     */
    @Validated
    public ParamEntity queryById(@NotNull(message = "请指定参数主键") String id) {
        return paramDao.queryById(id);
    }

    /**
     * 根据参数编码获取参数值
     *
     * @param code 参数编码
     * @return 返回参数编码对应的参数值
     */
    @Validated
    @Cacheable(key = "'param:code:'+#code")
    public ParamEntity queryByCode(@NotNull(message = "请指定参数编码") String code) {
        return paramDao.queryByCode(code);
    }


    /**
     * 查询参数列表
     *
     * @param params 查询参数
     * @return 返回符合查询条件的参数列表
     */
    @QueryMap
    public List<ParamEntity> query(Map params) {
        return paramDao.query(params);
    }

    /**
     * 查询参数分页列表
     *
     * @param params 查询参数
     * @return 返回符合查询条件的参数分页列表
     */
    @QueryMap
    public Page<ParamEntity> queryPage(Map params) {
        return (Page<ParamEntity>) paramDao.query(params);
    }

    /**
     * 生成历史记录对象
     */
    private HistoryModel.HistoryModelBuilder buildHistory() {
        return HistoryModel.builder()
                .tableName("sys_param")
                .tableCaption("系统参数")
                .keyName("id");
    }
}
